module client.RpcRequestsMap;

import core.stdc.time;
import std.stdio;
import msgtrans;
import message.Constants;
import message.MsgDefine;
import google.protobuf;
import client.ImClient;
import std.array;
import command.StartAppCommand;
import std.conv: to;
import hunt.logging;
import std.json;
import core.stdc.string;
import comm.comm;

struct RequestInfo
{
    ulong userId;
    ulong requestId;
    int src;
}


/**
 * Rpc请求跟踪表（用于连接超时判断）
 */
class RpcRequestsMap {

  private __gshared RpcRequestsMap _instance;

  private RequestInfo[][ulong] _forwardRequestMap;

  private uint _size;

  static public RpcRequestsMap getInstance()
  {
    if (_instance is null)
    {
      _instance = new RpcRequestsMap();
    }
    return _instance;
  }

  void addRequest(RequestInfo info)
  {
      synchronized(this) {
        _forwardRequestMap[core.stdc.time.time(null)] ~= info;
      }
  }

  void deleRequest(ulong time)
  {
      synchronized(this)
      {
         _forwardRequestMap.remove(time);
      }
  }

  void deleRequest(ulong userId, ulong requestId, int src)
  {
     synchronized(this){
      foreach (k , v ; _forwardRequestMap)
      {
          RequestInfo[] tmp;
          foreach(RequestInfo info ; v)
          {
              if(!(info.userId == userId && requestId == info.requestId && src == info.src))
              {
                tmp ~= info;
              }
          }
          _forwardRequestMap[k] = tmp;
     }
    }
  }

  void doWork()
  {
     //RequestInfo[][ulong] tmp;
     synchronized(this)
     {
       ulong time = core.stdc.time.time(null);
       foreach (k , v ; _forwardRequestMap)
       {
         if(time - k >= 2)
         {
           foreach(RequestInfo info ; v)
           {
             auto res = new RPC_RESPONSE();
             ErrorObj obj;
             obj.code = ErrorCode.ERR_RPCTIMEOUT;
             obj.message = "请求超时";
             res.content = EncodeJsonValue(obj);
             TransportSession client = ImClient.getInstance().getImClientByMixId(ImClient.getInstance().idMixSrc(info.userId, info.src));
             if (client !is null)
             {
               ClientExtend clientExtend;
               clientExtend.requestId = to!uint(info.requestId);

               ubyte[ClientExtend.sizeof] extend;
               memcpy(extend.ptr,&clientExtend,ClientExtend.sizeof);
               client.send( new MessageBuffer( MESSAGE.CMD_RPC_RESPONST,res.toProtobuf.array,extend));
             }
           }
           _forwardRequestMap.remove(k);
         }
       }
     }

  }
}
